package com.teamone.mobilewatch.xml;

import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import android.util.Log;

import com.teamone.mobilewatch.model.Patient;

/**
 * Processes xml string containing list of patients with patient specific data  
 * 
 */
public class PatientXmlProcessorImpl implements XmlProcessor<ArrayList<Patient>>{
	private final static String PATIENT_TAG = "Patient";  
	private final static String PATIENT_ID_TAG = "PatientId";
	private final static String FIRST_NAME_TAG = "FirstName";
	private final static String LAST_NAME_TAG = "LastName";
	private final static String DEPARTMENT_TAG = "Department";
	private final static String ROOM_TAG = "Room";
	private final static String GENDER_TAG = "Gender";

	private static PatientXmlProcessorImpl instance;
	
	private XmlPullParserFactory factory;
	private XmlPullParser xpp; 
	
	/**
	 * Constructs object
	 * 
	 * @throws XmlPullParserException
	 */
	private PatientXmlProcessorImpl() throws XmlPullParserException {
		factory = XmlPullParserFactory.newInstance();
		factory.setNamespaceAware(true);
		xpp = factory.newPullParser();
	}

	/**
	 * Returns singleton instance of the class
	 * 
	 * @throws XmlPullParserException
	 */
    public static synchronized PatientXmlProcessorImpl getInstance() throws XmlPullParserException {
        if (null == instance) {
                instance = new PatientXmlProcessorImpl();
        }
        return instance;
    }	
	

	/**
	 * Processes xml string
	 * 
	 * @return - array list of Patient objects 
	 */
	@Override
	public ArrayList<Patient> process(String xmlString) throws IOException, XmlPullParserException {
		ArrayList<Patient> patients = null;
		try {
			xpp.setInput(new StringReader(xmlString));
			
			int eventType;
			eventType = xpp.getEventType();
			String currentTag = null;
			Patient patient = null;
			patients = new ArrayList<Patient>();
			
			while (eventType != XmlPullParser.END_DOCUMENT) {
				
				// ->ArrayOfPatient\Patient
				if (eventType == XmlPullParser.START_TAG
						&& PATIENT_TAG.equals(xpp.getName())) {
					
					patient = new Patient();
					// iterate through child items of Patient element
					boolean parentTagEnd = false;
					while ( !parentTagEnd ) {
						switch (eventType) {
						case XmlPullParser.TEXT:
							String text = xpp.getText();
							if(PATIENT_ID_TAG.equals(currentTag)) {
								patient.setPatientId(Integer.parseInt(text.trim()));
							}else if(FIRST_NAME_TAG.equals(currentTag)) {
								patient.setFirstName(text.trim());
							}else if(LAST_NAME_TAG.equals(currentTag)) {
								patient.setLastName(text.trim());
							}
							else if(ROOM_TAG.equals(currentTag)) {
								patient.setRoom(text.trim());
							}else if(DEPARTMENT_TAG.equals(currentTag)) {
								patient.setDepartment(text.trim());
							}else if(GENDER_TAG.equals(currentTag)) {
								patient.setGender(text.trim());
							}
							break;
						case XmlPullParser.START_TAG:
							currentTag = xpp.getName();
							break;
						case XmlPullParser.END_TAG:
							currentTag = null;
							// check if this is the end of the parent tag  
							if (PATIENT_TAG.equals(xpp.getName())){
								// completed iteration on child elements - exit loop
								parentTagEnd = true;
							}
							break;
						default:
							break;
						}
						eventType = xpp.next();

					} // end while iteration on Patient
					// append to array list
					patients.add(patient);
				}

				eventType = xpp.next();
			} // end while

		} catch (IOException e) {
			Log.e("XmlProcessor", e.getMessage());
			throw e;
		} catch (XmlPullParserException e1) {
			Log.e("XmlProcessor", e1.getMessage());
			throw e1;
		}
		return patients;
	}
}
